package ru.nstu.isma.core.lang.ast.visitor;

import ru.nstu.isma.core.lang.ast.LismaBaseVisitor;
import ru.nstu.isma.core.lang.ast.LismaParser;
import ru.nstu.isma.core.hsm.HMState;
import ru.nstu.isma.core.hsm.HMStateAutomata;
import ru.nstu.isma.core.hsm.HMVariableTable;
import ru.nstu.isma.core.hsm.exp.HMExpression;
import org.antlr.v4.runtime.misc.NotNull;

import java.util.LinkedList;
import java.util.List;

/**
 * by Alexey Bessonov
 * Date: 03.12.13
 * Time: 1:18
 */
public class PopulateStateInfoVisitor extends LismaBaseVisitor<Object> {
    private HMVariableTable table;

    private HMStateAutomata automata;

    public PopulateStateInfoVisitor(HMVariableTable table, HMStateAutomata automata) {
        this.table = table;
        this.automata = automata;
    }

    @Override
    public Object visitState(@NotNull LismaParser.StateContext ctx) {
        // 1 ловим текущее состояние
        HMState to = automata.getState( ctx.getChild(1).getText());

        // 2 парсим условие перехода
        ExpressionVisitor ev = new ExpressionVisitor(table);
        HMExpression cond = ev.visit(ctx.getChild(3));

        // 3 делаем список состояний из которых выходим в текщее
        List<HMState> statesFrom = new LinkedList<HMState>();

        if (ctx.getChild(6) instanceof LismaParser.State_fromContext) {
            LismaParser.State_fromContext from = (LismaParser.State_fromContext) ctx.getChild(6);
            HMState sttemp;
            for (int i=0; i<from.getChildCount(); i++) {
                if (from.getChild(i) instanceof LismaParser.State_nameContext) {
                    sttemp = automata.getState( from.getChild(i).getText());
                    statesFrom.add(sttemp);
                }
            }
        }
        if (statesFrom.size() == 0) {
            // TODO преупреждение семантики - висячее состояние
        }
        // проставляем переходы
        for (HMState from : statesFrom) {
            automata.addTransaction(from, to, cond);
        }

        return null;
    }
}
